package com.lucy.disk.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.crypto.SecureUtil;
import com.lucy.common.constant.HttpStatus;
import com.lucy.common.domain.PageResultDTO;
import com.lucy.common.exception.BusinessException;
import com.lucy.disk.dao.FileEntityDAO;
import com.lucy.disk.domain.entity.FileEntity;
import com.lucy.disk.service.FileService;
import com.lucy.disk.utils.DiskUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.List;
import java.util.Optional;

/**
 * @author kindear
 */
@Slf4j
@Service
public class FileServiceImpl implements FileService {
    @Autowired(required = false)
    FileEntityDAO dao;


    @Override
    public FileEntity getOneUnwrap(String s) {
        Optional<FileEntity> entityOp = getOne(s);
        if (!entityOp.isPresent()){
            throw new BusinessException(HttpStatus.NOT_FOUND);
        }
        return entityOp.get();
    }

    @Override
    public FileEntity createDir(String parentDirId, String dirName,String userId) {
        // 简单初始化
        FileEntity fileEntity = new FileEntity(dirName);
        // 设置文件父目录
        fileEntity.setDirId(parentDirId);
        // 设置文件所属用户
        fileEntity.setUserId(userId);

        // 判断是否存在重复
        Example<FileEntity> example = Example.of(fileEntity);
        List<FileEntity> sameList = dao.findAll(example);
        if (sameList.size() > 0 ){
            throw new BusinessException(HttpStatus.FORBIDDEN,"重复目录");
        }
        // 设置类型
        fileEntity.setIsDir(1);

        // 配置文件大小
        fileEntity.setFileSize(0L);
        // 计算文件MD5
        fileEntity.setMd5("");

        return saveOne(fileEntity);
    }

    @Override
    public FileEntity createFile(String parentDirId, String fileName,String userId) {
        // 简单初始化
        FileEntity fileEntity = new FileEntity(fileName);
        // 设置文件父目录
        fileEntity.setDirId(parentDirId);
        // 设置文件所属用户
        fileEntity.setUserId(userId);

        // 判断文件名是否可以被创建
        if (!DiskUtil.isDoc(fileName)){
            throw new BusinessException(HttpStatus.FORBIDDEN,"禁止创建该类型文件");
        }
        // 判断是否存在重复
        Example<FileEntity> example = Example.of(fileEntity);
        List<FileEntity> sameList = dao.findAll(example);
        if (sameList.size() > 0 ){
            throw new BusinessException(HttpStatus.FORBIDDEN,"重复文件");
        }
        // 设置类型
        fileEntity.setIsDir(0);
        File newFile = FileUtil.touch(fileName);

        // 配置文件大小
        fileEntity.setFileSize(newFile.length());
        // 计算文件MD5
        fileEntity.setMd5(SecureUtil.md5(newFile));

        return saveOne(fileEntity);
    }

    @Override
    @Transactional
    public void batchDelete(List<String> ids) {
        dao.deleteByIdIn(ids);
    }

    @Override
    public List<FileEntity> batchGet(List<String> list) {
        return dao.findByIdIn(list);
    }

    @Override
    public PageResultDTO<FileEntity> getAll(Pageable pageable, Example<FileEntity> example) {
        Page<FileEntity> page;

        if(Validator.isEmpty(example)){
            page = dao.findAll(pageable);
        }
        else {
            page = dao.findAll(example,pageable);
        }
        List<FileEntity> list = page.getContent();
        PageResultDTO<FileEntity> pageResultDTO = new PageResultDTO<>();


        //封装分页请求结果
        pageResultDTO.setContent(list);
        pageResultDTO.setSize(page.getSize());
        pageResultDTO.setTotalPages(page.getTotalPages());
        pageResultDTO.setNumber(page.getNumber());
        pageResultDTO.setTotalElements(page.getTotalElements());
        return pageResultDTO;
    }

    @Override
    public List<FileEntity> getExample(Example<FileEntity> example) {
        return dao.findAll(example);
    }

    @Override
    public void deleteOne(String id) {
        Optional<FileEntity> fileOp = dao.findById(id);
        if (!fileOp.isPresent()){
            throw new BusinessException(HttpStatus.NOT_FOUND,"文件不存在");
        }
        FileEntity entity = fileOp.get();

        dao.deleteById(id);
    }

    @Override
    public Optional<FileEntity> getOne(String s) {
        return dao.findById(s);
    }

    @Override
    public FileEntity saveOne(FileEntity fileEntity) {
        if (Validator.isNotEmpty(fileEntity.getId())){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"ID参数错误");
        }
        return dao.save(fileEntity);
    }

    @Override
    public FileEntity updateOne(FileEntity fileEntity) {
        if (Validator.isEmpty(fileEntity.getId())){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"ID参数错误");
        }
        return dao.save(fileEntity);
    }
}
